let path = require('path');
let moment = require("moment");
let numeral = require("numeral");
let groupBy = require("lodash/groupBy");
let objectWithoutProperties = require('object-without-properties');
var knex = require('knex')({
  client: 'sqlite3',
  connection: {
    filename: path.join(__dirname, "../../../database.db")
  },
  debug: true,
  useNullAsDefault: true
});

function formatSerialNumber(serialNumber) {
  return serialNumber.prefix + serialNumber.date_str + numeral(serialNumber.number).format("0000");
}

function getProductClassTree(productClasses, classId) {
  if (productClasses[classId]) {
    return productClasses[classId].map(productClass => {
      productClass.children = getProductClassTree(productClasses, productClass.id);
      return productClass;
    })
  }
  else {
    return undefined;
  }
}
module.exports = {
  getClient: function (clientId) {
    return knex("client").where("id", clientId)
  },

  createSerialNumber: function (prefix) {
    return knex("serialnumber").where("prefix", prefix).limit(1)
      .then(function (rows) {
        var serialNumber = rows.length == 0 ? null : rows[0];
        var date_str = moment().format("YYYYMMDD");
        if (!serialNumber) {
          serialNumber = {
            "prefix": prefix,
            "date_str": date_str,
            "number": 1
          };
          return knex("serialnumber")
            .insert(serialNumber)
            .then(function () {
              return serialNumber;
            })
        }
        else if (serialNumber.date_str == date_str) {
          serialNumber.number += 1;
          return knex("serialnumber")
            .update({
              "number": serialNumber.number
            }).where("id", serialNumber.id)
            .then(function () {
              return serialNumber;
            })
        }
        else {
          serialNumber.number = 1;
          serialNumber.date_str = date_str;
          return knex("serialnumber")
            .update({
              "number": serialNumber.number,
              "date_str": serialNumber.date_str
            }).where("id", serialNumber.id)
            .then(function () {
              return serialNumber;
            })
        }
      })
      .then(function (serialNumber) {
        return formatSerialNumber(serialNumber)
      })

  },

  createProductInfo: function (productInfo) {
    var productInfo = objectWithoutProperties(productInfo, ["id"]);
    return knex("product_info").insert(productInfo);
  },

  getProductClasses: function () {
    return knex("product_class")
      .select()
      .then(function (rows) {
        var productClasses = groupBy(rows, "parent_id");
        return getProductClassTree(productClasses, 0);
      })
  },

  createProductClass: function ({ parent_id, text }) {
    return knex("product_class")
      .insert({ parent_id: parent_id, text: text })
      .then(function () {
        return knex("product_class").where({ text: text, parent_id: parent_id })
      })
      .then(function (newProductClass) {
        return newProductClass[0];
      })
  },

  updateProductClass: function (classId, productClass) {
    var productClass = objectWithoutProperties(productClass, ["id"]);
    return knex("product_class").where("id", classId).update(productClass);
  },

  getUnits: function () {
    return knex("unit").select()
      .then(function (units) {
        return units.map(function (unit) {
          unit.unit_isdeciaml = unit.unit_isdecimal == 1;
          return unit;
        })
      })
  },

  deleteUnit: function (unitIds) {
    return knex("unit").whereIn("id", unitIds).delete();   
  },

  createUnit: function (unit) {
    var unit = objectWithoutProperties(unit, ["id"]);
    return knex("unit").insert(unit)
      .then(function () {
        return knex("unit").where({ "unit_name": unit.unit_name })
      })
      .then(function (newUnits) {
        return newUnits[0];
      })
  }
}
